/*  This file is part of -_-.

    -_- is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    -_- is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with -_-.  If not, see <http://www.gnu.org/licenses/>.

    Copyright 2012-2013 Oliver Katz */

#include "data.h"
#include "debug.h"

z_typeid z_typeid_null = 0;
z_size z_size_empty = 0;

z_data z_data_init(z_typeid t, z_size s)
{
	z_data tmp = {
		t,
		s,
		NULL
	};

	return tmp;
}

z_data *z_data_new(z_typeid t, z_size s)
{
	z_data *tmp = (z_data *)malloc(sizeof(z_data));
	*tmp = z_data_init(t, s);
	return tmp;
}

int z_data_release(z_data d)
{
	if (d.src != NULL)
		free(d.src);
	return 0;
}

int z_data_delete(z_data *d)
{
	Z_WARNING_NULL(d, 1);
	z_data_release(*d);
	free(d);
	return 0;
}

z_typeid z_data_typeid_get(z_data *d)
{
	Z_WARNING_NULL(d, 0);
	return d->tid;
}

z_typeid z_data_typeid_set(z_data *d, z_typeid t)
{
	Z_WARNING_NULL(d, 0);
	return (d->tid = t);
}

z_size z_data_size_get(z_data *d)
{
	Z_WARNING_NULL(d, 0);
	return d->size;
}

z_size z_data_size_set(z_data *d, z_size s)
{
	Z_WARNING_NULL(d, 0);
	return (d->size = s);
}

void *z_data_src_get(z_data *d)
{
	Z_WARNING_NULL(d, NULL);
	return d->src;
}

void *z_data_src_set(z_data *d, void *s)
{
	Z_WARNING_NULL(d, NULL);
	return (d->src = s);
}

int z_data_retrieve_query_code(z_data *d)
{
	Z_WARNING_NULL(d, 0);
	return (int)d->src;
}

int z_data_assign_query_code(z_data *d, int c)
{
	Z_WARNING_NULL(d, 0);
	return (int)(d->src = (void *)(unsigned int)c);
}

int z_data_eq(z_data *a, z_data *b)
{
	Z_WARNING_NULL(a, 0);
	Z_WARNING_NULL(b, 0);
	return ((a->tid == b->tid && a->size == b->size) && a->src == b->src);
}

int z_data_null(z_data *d)
{
	Z_WARNING_NULL(d, 1);
	return ((d->tid == 0 && d->size == 0) && d->src == NULL);
}

z_data z_data_wrap(void *ptr, z_typeid t, z_size s)
{
	Z_WARNING_NULL(ptr, z_data_init(0, 0));
	if (s == 0)
	{
		Z_WARNING("cannot wrap empty data");
		return z_data_init(0, 0);
	}
	void *buf = malloc(s);
	memcpy(buf, ptr, s);
	z_data rtn = z_data_init(t, s);
	z_data_src_set(&rtn, buf);
	return rtn;
}

z_data *_z_data_wrap(void *ptr, z_typeid t, z_size s)
{
	Z_WARNING_NULL(ptr, NULL);
	if (s == 0)
	{
		Z_WARNING("cannot wrap empty data");
		return NULL;
	}
	z_data *tmp = (z_data *)malloc(sizeof(z_data));
	*tmp = z_data_wrap(ptr, t, s);
	return tmp;
}
